<template>
  <q-page>
    <div v-if="lockPage"></div>
    <div v-else class="container q-gutter-sm">
      <div class="row q-col-gutter-sm">
        <div class="col-xs-12">
          <q-field :label="$t('play.chartSource.label')" :disable="loading" stack-label borderless>
            <q-option-group inline v-model="chartSource" :options="chartSourceOptions" color="primary"/>
          </q-field>
        </div>
        <!--Bestdori!-->
        <div class="col-xs-12 row q-col-gutter-sm" v-if="chartSource === 'bestdori'">
          <div class="col-xs-12">
            <q-field :label="$t('play.chartSource.bestdori.type.label')" :disable="loading" stack-label borderless>
              <q-option-group inline v-model="chartType" :options="bestdoriChartTypeOptions" color="primary"/>
            </q-field>
          </div>
          <div class="col-xs-12">
            <q-input dense
                     :label="$t('play.chartSource.bestdori.chartId')"
                     :disable="loading"
                     v-model.number="chartId"
                     type="number"
                     :hint="$t(`play.chartSource.bestdori.type.${chartType}.hint`)">
              <template v-slot:append>
                <q-btn round flat icon="update" @click="isFindDialogDisplay = true"/>
                <find v-model="isFindDialogDisplay" @click="onFindClickEvent"/>
                <q-btn round flat v-show="chartType === 'official'" icon="list"
                       @click="isOfficialSongListDisplay = true"/>
                <official-list v-model="isOfficialSongListDisplay"/>
                <q-btn round flat v-show="false" icon="search"
                       @click="isCommunitySearchDialogDisplay = true"/>
                <community-search v-model="isCommunitySearchDialogDisplay"/>
              </template>
            </q-input>
          </div>
          <div class="col-xs-12" v-if="chartInfo">
            <q-card class="q-pa-md" style="margin-top: 72px;">
              <div class="row q-col-gutter-md">
                <!--封面图和难度展示-->
                <div class="col-xs-12 col-sm-4 col-md-3 text-center row q-col-gutter-md"
                     style="margin-top: -72px;">
                  <div class="col-xs-12">
                    <div class="relative-position" style="width: 100%; max-width: 208px; margin: 0 auto">
                      <q-img :src="setProxyUrl(chartInfo.cover, options.baseUrl)"
                             :ratio="1"
                             class="shadow-12"
                             width="100%"/>
                      <q-btn class="absolute-bottom-right"
                             style="margin: 8px 8px 8px 8px;"
                             round
                             color="pink"
                             :icon="isFavorite ? 'favorite' : 'favorite_border'"
                             size="md"
                             @click="isInList(chartSource, chartType, chartId) ?
                                     removeFavorite(chartSource, chartType, chartId) :
                                     addFavorite(chartSource, chartType, chartId, chartInfo.title, chartInfo.artist, chartInfo.author)"/>
                    </div>
                  </div>
                  <div class="col-xs-12">
                    <diff-icon-list :diffs="chartInfo.difficulty" :size="28" :center="true"/>
                  </div>
                </div>
                <!--歌曲信息展示-->
                <div class="col-xs-12 col-sm-8 col-md-9">
                  <div class="row q-col-gutter-sm">
                    <div class="col-xs-12 text-h4">{{ chartInfo.title }}</div>
                    <div class="col-xs-12 text-h5">{{ chartInfo.artist }}</div>
                    <div class="col-xs-12 text-h6" v-if="chartInfo.type === 'community'">{{ chartInfo.author }}</div>
                  </div>
                </div>
              </div>
            </q-card>
            <q-btn-toggle v-if="chartInfo.type === 'official'"
                          class="q-mt-sm"
                          v-model="officialDiff"
                          toggle-color="primary"
                          :options="chartInfo.difficulty"
                          :disable="loading" spread/>
          </div>
          <div class="col-xs-12">
            <q-btn class="full-width"
                   color="primary"
                   :disable="loading"
                   :loading="loading"
                   :label="!chartInfo ? $t('play.load.label') : $t('play.start.label')"
                   @click="!chartInfo ? bestdoriLoad() : start()">
              <template v-slot:loading>
                <div class="row q-col-gutter-md">
                  <q-spinner-cube size="lg" class="col-auto"/>
                  <div class="col-auto">{{ $t(loadingText.text) }}</div>
                </div>
              </template>
            </q-btn>
          </div>
        </div>
        <!--Local-->
        <div class="col-xs-12 row q-col-gutter-sm" v-else-if="chartSource === 'local'">
          <div class="col-xs-12">
            <q-field :label="$t('play.chartSource.local.type.label')" :disable="loading" stack-label borderless>
              <q-option-group inline v-model="chartType" :options="localChartTypeOptions" color="primary"/>
            </q-field>
          </div>
          <div class="col-xs-12 row q-col-gutter-sm" v-if="chartType === 'bangpack'">
            <div class="col-xs-12" v-if="chartInfo">
              <q-card class="q-pa-md" style="margin-top: 72px;">
                <div class="row q-col-gutter-md">
                  <!--封面图和难度展示-->
                  <div class="col-xs-12 col-sm-4 col-md-3 text-center row q-col-gutter-md"
                       style="margin-top: -72px;">
                    <div class="col-xs-12">
                      <div class="relative-position" style="width: 100%; max-width: 208px; margin: 0 auto">
                        <q-img :src="chartInfo.cover"
                               :ratio="1"
                               class="shadow-12"
                               width="100%"/>
                      </div>
                    </div>
                    <div class="col-xs-12">
                      <diff-icon-list :diffs="chartInfo.difficulty" :size="28" :center="true"/>
                    </div>
                  </div>
                  <!--歌曲信息展示-->
                  <div class="col-xs-12 col-sm-8 col-md-9">
                    <div class="row q-col-gutter-sm">
                      <div class="col-xs-12 text-h4">{{ chartInfo.title }}</div>
                      <div class="col-xs-12 text-h5">{{ chartInfo.artist }}</div>
                      <div class="col-xs-12 text-h6">{{ chartInfo.author }}</div>
                    </div>
                  </div>
                </div>
              </q-card>
              <q-btn-toggle v-if="chartInfo.difficulty"
                            class="q-mt-sm"
                            toggle-color="primary"
                            v-model="bangpackDiff"
                            :options="chartInfo.difficulty"
                            :disable="loading"
                            spread/>
            </div>
            <div class="col-xs-12">
              <q-btn class="full-width" color="primary"
                     :disable="loading"
                     :loading="loading"
                     :label="chartInfo ?
                             $t('play.chartSource.local.type.start') :
                             $t('play.chartSource.local.type.bangpack.select')"
                     @click="chartInfo ? start() : chooseBanGPack()">
                <template v-slot:loading>
                  <div class="row q-col-gutter-md">
                    <q-spinner-cube size="lg" class="col-auto"/>
                    <div class="col-auto">{{ $t(loadingText.text) }}</div>
                  </div>
                </template>
              </q-btn>
              <input type="file"
                     ref="bangpackInput"
                     accept=".bangpack, application/zip"
                     style="display: none"
                     @change="onBanGPackChangeEvent"/>
            </div>
          </div>
          <div class="col-xs-12 row q-col-gutter-sm" v-else>
            <div class="col-xs-12">
              <q-input v-model="localChart" type="textarea" :disable="loading"/>
            </div>
            <div class="col-xs-12">
              <q-btn class="full-width"
                     :disable="loading"
                     color="primary"
                     :label="$t(`play.chartSource.local.type.${chartType}.select`)"
                     @click="chooseLocalChart"/>
              <input type="file"
                     ref="localChartInput"
                     accept="application/json"
                     style="display: none"
                     @change="onLocalChartChangeEvent"/>
            </div>
            <div class="col-xs-12">
              <q-file :label="$t(`play.chartSource.local.type.select.audio.label`)"
                      :value="localAudio" @input="onLocalAudioChangeEvent" accept="audio/*"/>
            </div>
            <div class="col-xs-12">
              <q-file :label="$t(`play.chartSource.local.type.select.cover.label`)"
                      :value="localCover" @input="onLocalCoverChangeEvent" accept="image/*"/>
            </div>
            <div class="col-xs-12">
              <q-input v-model="localSongName"
                       :label="$t(`play.chartSource.local.type.select.songName.label`)"/>
            </div>
            <div class="col-xs-12">
              <q-btn :disable="loading || !localAudio || localSongName.length <= 0"
                     :loading="loading"
                     class="full-width"
                     color="primary"
                     :label="$t('play.chartSource.local.type.start')"
                     @click="start"/>
            </div>
          </div>
          <div class="col-xs-12 text-caption text-grey" v-show="!chartInfo && chartType === 'bangpack'">
            {{ $t('play.chartSource.local.type.bangpack.hint') }}
          </div>
        </div>
      </div>
      <u-dialog v-model="isDownloadDialogDisplay"
                type="wait" :title="$t('INFO_GETTING_DATA')">
        <div class="q-gutter-sm">
          <div>
            <q-linear-progress :value="downloadProgress / downloadTotal"/>
          </div>
          <div class="text-center text-body1">
            {{ Math.round(downloadProgress / 1024 / 1024 * 100) / 100 }}MB/{{ Math.round(downloadTotal / 1024 / 1024 * 100) / 100 }}MB</div>
          <div class="text-center text-caption text-grey">{{ downloadSpeed }}</div>
        </div>
      </u-dialog>
    </div>
    <q-page-sticky position="bottom-right" :offset="[18, 18]"
                   v-if="chartInfo != null || (localAudio && localSongName.length > 0)">
      <q-fab icon="keyboard_arrow_up" direction="up" color="red">
        <q-fab-action color="orange" icon="share" @click="createShareLink" v-if="chartSource === 'bestdori'"/>
        <u-dialog :title="$t('share.title')"
                  type="none"
                  v-model="isShareDialogOpen">
          <q-input readonly
                   v-model="shareLink"
                   :hint="$t('share.tip')"/>
        </u-dialog>
        <q-fab-action color="green" icon="code" @click="isModDialogDisplay = true"/>
        <mod v-model="isModDialogDisplay"/>
        <q-fab-action color="blue" icon="get_app" @click="getLocalPack"
                      v-if="chartSource === 'bestdori' ||
                       (chartSource === 'local' && ['bangbangboomv2', 'bestdori', 'banground'].includes(chartType))"/>
      </q-fab>
    </q-page-sticky>
  </q-page>
</template>

<script>
  import notify from 'src/lib/notifyUtil';
  import * as optionUtil from 'src/lib/playerOptionUtil';
  import * as bestdori from 'src/lib/bestdoriAPI';
  import * as contentUtil from 'src/lib/contentUtil';
  import * as favorite from 'src/lib/favoriteUtil';
  import {isInList} from 'src/lib/favoriteUtil';
  import setProxyUrl from "src/lib/proxyUtil";
  import DiffIconList from "src/components/player/DiffIconList";
  import OfficialList from "src/pages/player/OfficialList";
  import CommunitySearch from "src/pages/player/CommunitySearch";
  import {enableMod, toModName} from "src/lib/modUtil";
  import Mod from "src/pages/player/Mod";
  import {copyToClipboard} from 'quasar'
  import {createLocalPack, handleBatchDownload, loadLocalPack} from "src/lib/localPackUtil";
  import {readFile} from 'src/lib/fileUtil';
  import UDialog from "src/components/public/UDialog";
  import Find from "src/pages/player/Find";
  import * as statistics from 'src/lib/statisticsUtil.js';
  import {getHistoryList, newHistory} from "src/lib/historyUtil";
  import screenfull from 'screenfull';

  export default {
    name: 'PageIndex',
    components: {Find, UDialog, OfficialList, CommunitySearch, DiffIconList, Mod},
    data: function () {
      return {
        loadingText: {
          text: ''
        },
        lockPage: false,

        diffColor: {
          Easy: '#57c0c9',
          Normal: '#8ac957',
          Hard: '#efa119',
          Expert: '#c76060',
          Special: '#c360c7'
        },

        options: null,

        chartSource: 'bestdori',
        isFavorite: false,

        chartType: 'community',

        chartId: 19078,
        chartInfo: null,
        officialDiff: 'Expert',

        isOfficialSongListDisplay: false,
        isCommunitySearchDialogDisplay: false,
        isModDialogDisplay: false,

        bangpackFile: null,
        bangpackDiff: '',

        isShareDialogOpen: false,
        shareLink: '',

        localChart: '',
        localAudio: null,
        localCover: null,
        localSongName: '',

        isFindDialogDisplay: false,

        isDownloadDialogDisplay: false
      };
    },
    watch: {
    },
    computed: {
      chartSourceOptions() {
        return [
          {
            label: this.$t('play.chartSource.bestdori.label'),
            value: 'bestdori'
          },
          {
            label: this.$t('play.chartSource.local.label'),
            value: 'local'
          }
        ];
      },
      bestdoriChartTypeOptions() {
        return [
          {
            label: this.$t('play.chartSource.bestdori.type.community.label'),
            value: 'community'
          },
          {
            label: this.$t('play.chartSource.bestdori.type.official.label'),
            value: 'official'
          }
        ];
      },
      localChartTypeOptions() {
        return [
          {
            label: this.$t('play.chartSource.local.type.bangpack.label'),
            value: 'bangpack'
          },
          {
            label: this.$t('play.chartSource.local.type.bangbangboomv2.label'),
            value: 'bangbangboomv2'
          },
          {
            label: this.$t('play.chartSource.local.type.bestdori.label'),
            value: 'bestdori'
          }
        ];
      },
      langIndex() {
        let option = optionUtil.readPlayerOptions();
        let lang = option.language;
        if (lang.toLowerCase().includes('en_')) return 1;
        else if (lang.toLowerCase() === 'zh_tw') return 2;
        else if (lang.toLowerCase().includes('zh_')) return 3;
        else if (lang.toLowerCase().includes('ko_')) return 4;
        else return 0;
      },
      downloadProgress: {
        get() {
          return this.$store.state.downloadProgress;
        }
      },
      downloadTotal: {
        get() {
          if (this.$store.state.downloadTotal) return this.$store.state.downloadTotal;
          return 0;

        }
      },
      downloadSpeed: {
        get() {
          return this.$store.state.downloadSpeed;
        }
      },
      loading: {
        get() {
          return this.$store.state.loading;
        },
        set(v) {
          this.$store.commit('setLoading', v)
        }
      }
    },
    watch: {
      chartType() {
        this.chartInfo = null;
      },
      chartId() {
        this.chartInfo = null;
      },
      chartInfo() {
        this.isFavorite = isInList(this.chartSource, this.chartType, this.chartId)
      },
      chartSource() {
        if (this.chartSource === 'bestdori') this.chartType = this.bestdoriChartTypeOptions[0].value;
        else if (this.chartSource === 'local') this.chartType = this.localChartTypeOptions[0].value;
      }
    },
    methods: {
      async preload(source, type, id, diff, mod, autoload) {
        //1.3版本重制：读取query数据后暂存到store内，然后重定向到网页，来达到清除query的目的
        let preloadData = {
          source: this.chartSource,
          type: this.chartType,
          id: this.chartId,
          diff: this.officialDiff,
          autoload: false
        };
        if (source)
          this.chartSourceOptions.forEach(item => {
            if (item.value === source.toLowerCase() && item.value != 'local') preloadData.source = item.value;
          })
        if (type)
          if (preloadData.source === 'bestdori')
            if (type === 'official') preloadData.type = 'official';
            else preloadData.type = 'community';
        if (id) preloadData.id = id;
        if (diff && preloadData.type === 'official' && bestdori.diffName.includes(diff)) preloadData.diff = diff;
        if (mod) {
          let modList = mod.split(',');
          if (modList.length > 0) modList.forEach(item => {
            this.$store.commit('setNoteChangeMod', toModName(item))
          })
        }
        if (autoload) preloadData.autoload = true;
        this.$store.commit('setPreload', preloadData);
        if (source || type || id || diff || mod || autoload) await this.$router.push('/');
      },
      async bestdoriLoad() {
        this.loading = true;
        try {
          if (this.chartId <= 0) throw new Error('ERR_WRONG_CHART_ID');
          let chartInfo;
          if (this.chartType === 'community') chartInfo = await bestdori.getCommunityChart(this.chartId, this.loadingText);
          else if (this.chartType === 'official') chartInfo = await bestdori.getOfficialChartInfo(this.chartId, this.langIndex, this.loadingText);
          else throw new Error('ERR_INVALID_ARGUMENT');
          let last = {
            chartSource: this.chartSource,
            chartType: this.chartType,
            chartId: this.chartId
          };
          this.$q.localStorage.set('BanG_Player_last', last);
          this.chartInfo = chartInfo;

          if (this.chartInfo.difficulty.indexOf(this.officialDiff) < 0)
            this.officialDiff = this.chartInfo.difficulty[this.chartInfo.difficulty.length - 1].type;
        } catch (e) {
          notify(this.$t('public.error'), this.$t(e.message), 'clear');
        }
        this.loading = false;
      },
      async start() {
        this.loading = true;
        try {
          this.options = optionUtil.readPlayerOptions();
          let gameConfig = this.options.gameConfig;
          let gameLoadConfig;
          let gameChart;
          if (this.chartSource === 'bestdori') {
            let bdMap = await this.toBestdoriMap();
            gameChart = bdMap.gameChart;
            gameLoadConfig = {
              musicSrc: bdMap.musicSrc,
              backgroundSrc: bdMap.backgroundSrc,
              songName: bdMap.songName
            }
            try {
              let history = getHistoryList();
              if (history.length === 0 || new Date().getTime() - history[history.length - 1].time > 30000)
                await statistics.newPlay(this.chartSource, this.chartType, this.chartId, this.chartInfo.title, this.chartInfo.artist, this.chartInfo.author);
            } catch (e) {
            }
            newHistory(this.chartSource, this.chartType, this.chartId, bdMap.songName);
          } else if (this.chartSource === 'local' && this.chartType === 'bangpack') {
            gameChart = this.chartInfo.mapContent[this.bangpackDiff];
            gameLoadConfig = {
              musicSrc: this.chartInfo.audio,
              backgroundSrc: this.getBackgroundSrc(this.chartInfo.cover),
              songName: this.chartInfo.title
            }
          } else if (this.chartSource === 'local' && ['bangbangboomv2', 'bestdori', 'banground'].includes(this.chartType)) {
            if (this.chartType === 'bangbangboomv2') gameChart = contentUtil.bangbangboomv2(JSON.parse(this.localChart));
            else if (this.chartType === 'bestdori') gameChart = contentUtil.bestdori(JSON.parse(this.localChart));
            else throw new Error('ERR_UNKNOWN_CHART_TYPE');
            gameLoadConfig = {
              musicSrc: await readFile(this.localAudio, 'dataurl'),
              backgroundSrc: this.getBackgroundSrc(this.localCover ?
                await readFile(this.localCover, 'dataurl') :
                `statics/img/jacket.png`),
              songName: this.localSongName
            }
          }
          //启用mod
          gameLoadConfig.mapContent = () => enableMod(gameChart, [this.$store.getters.noteChangeMod]);
          //显示mod名称
          if (this.$store.getters.noteChangeMod != 'none')
            gameLoadConfig.songName = `[${this.$t(`mod.${this.$store.getters.noteChangeMod}.name`)}] ${gameLoadConfig.songName}`;
          //设定皮肤和音效
          gameLoadConfig.skin = `statics/player/skins/${this.options.skin}`;
          gameLoadConfig.sound = `statics/player/skins/${this.options.sound === 'skin' ? this.options.skin : this.options.sound}`;

          //进度下载资源，成功获取就替换掉原先的url
          //大量事实表明，有个进度条可以极大提升用户体验
          let bAudio, bCover;
          try {
            bAudio = await this.onDownload(gameLoadConfig.musicSrc);
            gameLoadConfig.musicSrc = await readFile(bAudio, 'dataurl');
            bCover = await this.onDownload(gameLoadConfig.backgroundSrc);
            gameLoadConfig.backgroundSrc = await readFile(bCover, 'dataurl');
          } catch {}

          this.$store.commit('setGameConfig', gameConfig);
          this.$store.commit('setGameLoadConfig', gameLoadConfig);

          try {
            if (this.options.autoFullscreen && !screenfull.isFullscreen) await screenfull.request();
          } catch (e) {
            notify(this.$t('public.error'), this.$t('ERR_FULLSCREEN'), 'clear');
          }

          await this.$router.push('/game');
        } catch (e) {
          notify(this.$t('public.error'), this.$t(e.message), 'clear');
        }
        this.loading = false;
      },
      async toBestdoriMap() {
        this.options = optionUtil.readPlayerOptions();
        if (!this.chartInfo) throw new Error('ERR_NO_CHART_INFO');
        let gameChart;
        this.loadingText.text = 'INFO_CONVERTING_CHART';
        if (this.chartType === 'community')
          gameChart = contentUtil.bestdori(this.chartInfo.notes)
        else if (this.chartType === 'official') {
          let chart = await bestdori.getOfficialChart(this.chartId, this.officialDiff, this.loadingText);
          gameChart = contentUtil.bestdori(chart);
        }
        //设定音乐链接
        let musicSrc = setProxyUrl(this.chartInfo.audio, this.options.baseUrl);
        //设定背景图片链接
        let backgroundSrc = this.getBackgroundSrc(setProxyUrl(this.chartInfo.cover, this.options.baseUrl));
        //设定显示标题
        let songName = this.chartInfo.title;
        return {gameChart, musicSrc, backgroundSrc, songName};
      },
      getBackgroundSrc(coverUrl) {
        let backgroundSrc;
        this.options = optionUtil.readPlayerOptions();
        if (this.options.bg === 'skin') backgroundSrc = `statics/player/skins/${this.options.skin}/liveBG_normal.png`;
        else if (this.options.bg === 'cover') backgroundSrc = coverUrl;
        else if (this.options.bg === 'custom') backgroundSrc = this.options.customBg;
        else backgroundSrc = `statics/player/skins/${this.options.bg}/liveBG_normal.png`;
        return backgroundSrc;
      },
      setProxyUrl,
      isInList,
      addFavorite(a, b, c, d, e, f) {
        if (favorite.add(a, b, c, d, e, f))
          notify(this.$t('public.success'), this.$t('favorite.FAVORITE_ADDED', {title: this.chartInfo.title}), 'check');
        else notify(this.$t('public.failed'), this.$t('favorite.FAVORITE_ADD_FAILED', {title: this.chartInfo.title}), 'clear');
        this.isFavorite = isInList(this.chartSource, this.chartType, this.chartId)
      },
      removeFavorite(a, b, c) {
        if (favorite.remove(a, b, c))
          notify(this.$t('public.success'), this.$t('favorite.FAVORITE_REMOVED', {title: this.chartInfo.title}), 'check');
        else notify(this.$t('public.failed'), this.$t('favorite.FAVORITE_REMOVE_FAILED', {title: this.chartInfo.title}), 'clear');
        this.isFavorite = isInList(this.chartSource, this.chartType, this.chartId)
      },
      createShareLink() {
        if (this.chartInfo) {
          let shareUrl = `https://reikohaku.gitee.io/bang-player/#/?`;
          shareUrl = `${shareUrl}source=${this.chartSource}&type=${this.chartType}&id=${this.chartId}&autoload=true`;
          if (this.chartType === 'official') shareUrl = `${shareUrl}&diff=${this.officialDiff.toLowerCase()}`;
          if (this.$store.getters.noteChangeMod !== 'none') {
            shareUrl = `${shareUrl}&mod=${this.$store.getters.noteChangeMod}`
          }
          this.shareLink = shareUrl;
          copyToClipboard(shareUrl).then(() => {
            notify(this.$t('public.success'), this.$t('INFO_COPIED'), 'check');
          }).catch(() => {
            notify(this.$t('public.failed'), this.$t('INFO_COPY_FAILED'), 'clear');
            this.isShareDialogOpen = true;
          })
        }
      },
      async getLocalPack() {
        this.$q.loading.show({
          message: this.$t('INFO_GETTING_DATA')
        });
        try {
          this.options = optionUtil.readPlayerOptions();
          if (this.chartSource === 'bestdori') {
            if (!this.chartInfo) throw new Error('ERR_NO_CHART');
            let bdMap = await this.toBestdoriMap();
            this.$q.loading.hide();
            let audioData = await this.onDownload(setProxyUrl(this.chartInfo.audio, this.options.baseUrl));
            let coverData = await this.onDownload(setProxyUrl(this.chartInfo.cover, this.options.baseUrl));
            this.$q.loading.show({
              message: this.$t('INFO_GETTING_DATA')
            });
            let difficulty = this.chartInfo.difficulty;
            let gameChart = {};
            for (const item of difficulty) {
              if (this.chartType === 'community') gameChart[item.type] = bdMap.gameChart;
              else if (this.chartType === 'official') {
                let chart = await bestdori.getOfficialChart(this.chartInfo.id, item.type.toLowerCase());
                gameChart[item.type] = contentUtil.bestdori(chart);
              } else throw new Error('ERR_UNKNOWN_CHART_TYPE');
            }
            let songName = bdMap.songName;
            this.$q.loading.show({
              message: this.$t('INFO_PACKING')
            });
            await createLocalPack(audioData, coverData, gameChart, songName,
              this.chartInfo.artist, this.chartInfo.author, this.chartInfo.difficulty);
          } else if (this.chartSource === 'local' && ['bangbangboomv2', 'bestdori', 'banground'].includes(this.chartType)) {
            let audioData = await readFile(this.localAudio, 'arraybuffer');
            let coverData = this.localCover ?
              await readFile(this.localCover, 'arraybuffer') :
              await handleBatchDownload(`statics/img/jacket.png`);
            let gameChart = {Expert: {}};
            if (this.chartType === 'bangbangboomv2') gameChart.Expert = contentUtil.bangbangboomv2(JSON.parse(this.localChart));
            else if (this.chartType === 'bestdori') gameChart.Expert = contentUtil.bestdori(JSON.parse(this.localChart));
            else throw new Error('ERR_UNKNOWN_CHART_TYPE');
            let songName = this.localSongName;
            this.$q.loading.show({
              message: this.$t('INFO_PACKING')
            });
            await createLocalPack(audioData, coverData, gameChart, songName,
              '', '', [{
                type: 'Expert',
                level: 0,
                notes: gameChart.Expert.notes.length,
                label: 'Expert',
                value: 'Expert'
              }]);
          }
        } catch (e) {
          notify(this.$t('public.error'), this.$t(e.message), 'clear');
        }
        this.loading = false;
        this.$q.loading.hide();
      },
      chooseBanGPack() {
        this.$refs.bangpackInput.click();
      },
      async onBanGPackChangeEvent(event) {
        this.loading = true;
        this.loadingText.text = 'INFO_LOADING_BANGPACK';
        try {
          const files = event.target.files;
          let pack = await loadLocalPack(files[0]);
          this.chartInfo = {
            title: pack.title,
            artist: pack.artist,
            author: pack.author,
            difficulty: pack.difficulty,
            mapContent: pack.mapContent
          };
          this.chartInfo.audio = await readFile(pack.audio, 'dataurl');
          this.chartInfo.cover = await readFile(pack.cover, 'dataurl');
          this.bangpackDiff = this.chartInfo.difficulty[this.chartInfo.difficulty.length - 1].type;
        } catch (e) {
          notify(this.$t('public.error'), this.$t('ERR_LOAD_FILE_ERROR'), 'clear');
        }
        this.loading = false;
      },
      chooseLocalChart() {
        this.$refs.localChartInput.click();
      },
      async onLocalChartChangeEvent(event) {
        this.loading = true;
        try {
          const files = event.target.files;
          let chart = await readFile(files[0]);
          this.localChart = chart;
        } catch (e) {
          notify(this.$t('public.error'), this.$t('ERR_LOAD_FILE_ERROR'), 'clear');
        }
        this.loading = false;
      },
      onLocalAudioChangeEvent(event) {
        this.localAudio = event;
      },
      onLocalCoverChangeEvent(event) {
        this.localCover = event;
      },
      onFindClickEvent(source, type, id) {
        this.chartSource = source;
        this.chartType = type;
        this.chartId = id;
        if (this.chartSource === 'bestdori') this.bestdoriLoad();
      },
      async onDownload(url) {
        this.loading = true;
        this.isDownloadDialogDisplay = true;
        let data;
        try {
          this.$store.commit('resetDownload');
          data = await handleBatchDownload(url, this.$store);
        } catch (e) {
          throw e;
        } finally {
          this.isDownloadDialogDisplay = false;
          this.loading = false;
        }
        return data;
      }
    },
    async mounted() {
      let that = this;
      //启动时判断客户端UA，如果是QQ或微信内部浏览器，锁定页面，不允许访问
      //这是为了用户好
      if (this.$q.platform.userAgent.indexOf('MQQBrowser') >= 0 || this.$q.platform.userAgent.indexOf('micromessenger') >= 0)
        this.$router.push('/lock');

      //判断是否使用Chrome浏览器，不是则礼貌地提醒用户
      if (!this.$q.platform.is.chrome) notify(this.$t('public.notChrome'), '', 'info');

      this.options = optionUtil.readPlayerOptions();

      //绑定全局方法以供外部组件使用
      //从Favorite读取的事件
      this.$root.$on('loadByFavorite', function (item) {
        if (that.loading) return;
        that.chartInfo = null;
        that.chartSource = item.source;
        that.chartType = item.type;
        that.chartId = item.id;
        if (that.chartSource === 'bestdori') that.bestdoriLoad();
      });
      //从Favorite列表删除项目的事件
      this.$root.$on('onRemoveFavoriteEvent', function (item) {
        if (that.chartSource === item.source && that.chartType === item.type && that.chartId === item.id)
          that.isFavorite = false;
      });
      //从OfficialSongsList读取的事件
      this.$root.$on('loadByOfficialSongList', function (id) {
        that.chartSource = 'bestdori';
        that.chartType = 'official';
        that.chartId = id;
        that.bestdoriLoad();
      });
      //从CommunitySearch读取的事件
      this.$root.$on('loadByCommunitySearch', function (id) {
        that.chartSource = 'bestdori';
        that.chartType = 'community';
        that.chartId = id;
        that.bestdoriLoad();
      });

      //读取上次成功载入的谱面
      let last = this.$q.localStorage.getItem('BanG_Player_last');
      if (last.chartSource) this.chartSource = last.chartSource;
      if (last.chartType) this.chartType = last.chartType;
      if (last.chartId) this.chartId = last.chartId;

      //预读取参数
      this.preload(this.$route.query.source, this.$route.query.type, this.$route.query.id, this.$route.query.diff, this.$route.query.mod, this.$route.query.autoload);
      if (this.$store.getters.preload != null) {
        this.chartSource = this.$store.getters.preload.source;
        this.chartType = this.$store.getters.preload.type;
        this.chartId = this.$store.getters.preload.id;
        this.officialDiff = this.$store.getters.preload.diff;
        if (this.$store.getters.preload.autoload) {
          if (this.chartSource === 'bestdori') await this.bestdoriLoad();
        }
        this.$store.commit('setPreload', null);
      }
    }
  }
</script>

